#include "ProcessCreator.h"

#include <unistd.h>
#include <sys/wait.h>

#include "Utility.h"
#include "Log.h"
#include "ErrorCode.h"

ProcessCreator::ProcessCreator()
{
    //ctor
}

ProcessCreator::~ProcessCreator()
{
    //dtor
}



 int ProcessCreator::runProcess(const std::string_view& pathFile, const std::string_view& program, const char * args[]) {
    *args = program.data();

    std::string message{"exec "};
    message.reserve(STRING_BUFFER_SIZE << 1);
    message.append(pathFile);
    message.append(1, ' ').append(args[0]);
    if (args[1]) {
        message.append(1, ' ').append(args[1]);
        if (args[2]) {
            message.append(1, ' ').append(args[2]);
            if (args[3]) {
                message.append(1, ' ').append(args[3]);
            }
        }
    }
    LOG_DEDUG(message.data());

    __pid_t pid = fork();
    int code = 0;
    if (0 == pid) {

        code = execv(pathFile.data(), const_cast <char * const*>(args));
        if (0 > code) {

            LOG_ERROR(buildErrorMessage(code, errno, message).data());
            exit(-1);
        } else {
            LOG_DEDUG("%s,successfully!", message.data());
        }
    } else {
        pid = ::waitpid(pid, &code, WUNTRACED);
    }

    return code;
}


int ProcessCreator::createBackgroundProcess(const std::string_view& pathFile, const std::string_view& program, const char * args[]){
    *args = program.data();

    std::string message{"exec "};
    message.reserve(STRING_BUFFER_SIZE << 1);
    message.append(pathFile);
    message.append(1, ' ').append(args[0]);
    if (args[1]) {
        message.append(1, ' ').append(args[1]);
        if (args[2]) {
            message.append(1, ' ').append(args[2]);
            if (args[3]) {
                message.append(1, ' ').append(args[3]);
            }
        }
    }
    LOG_DEDUG(message.data());

    int code = 0;
    __pid_t pid = fork();
    if (0 == pid) {
        setsid();
//        fclose(stdout);
        code = execv(pathFile.data(), const_cast <char * const*>(args));
        if (0 > code) {

            LOG_ERROR(buildErrorMessage(code, errno, message).data());
            exit(-1);
        } else {
            LOG_DEDUG("%s,successfully!", message.data());
        }
    }

    return pid;
}



